package com.bigdatastudio.common.Utils;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Property;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
 * @author xiao_jie <br>
 * {@code @date} 2022/9/12 15:45 <br>
 * {@code @describe} mybatis-plus代码生成器 , 慎用！！！ 启动会覆盖源文件！！！
 */
@SuppressWarnings({"NewClassNamingConvention", "unused"})
public class MybatisPlusGenerator {

    /**
     * <h2>清新简洁版</h2>
     * <h3>(覆盖生成文件模式已开启)</h3>
     */
    @Test
    public void main() {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/big-data-application-studio?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true", "root", "zhj123")
                .globalConfig(builder -> {
                    builder.author("xiao_jie") // 设置作者
//                            .enableSwagger() // 开启 swagger 模式
//                            .fileOverride()// 覆盖已生成文件
                            .outputDir("E:\\CodeRoom\\bigDataStudio\\src\\main\\java"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.bigDataStudio") // 设置父包名
                            .serviceImpl("serviceImpl")
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "E:\\CodeRoom\\bigDataStudio\\src\\main\\resources\\Mapper")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude() // 设置需要生成的表名
                            .addTablePrefix("sys_", "ow_") // 设置过滤表前缀
                            .mapperBuilder()
                            .enableBaseResultMap() //mapper.xml文件中生成：BaseResultMap
                            .enableBaseColumnList()
                            .entityBuilder().enableLombok().idType(IdType.AUTO)
                            .controllerBuilder().enableRestStyle(); //mapper.xml文件中生成：通用查询结果列<sql id="Base_Column_List">
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }

    /**
     * <h2>至尊奢华版</h2>
     * <h3>(覆盖生成文件模式已开启)</h3>
     */
    public static void main(String[] args) {

        // 手动设置工程路径
        System.out.print("请输入工程路径：");
        Scanner myScanner = new Scanner(System.in);
        String projectPath = myScanner.nextLine();
        if ("".equals(projectPath)) {
            // 自动获取当前工程路径（对子模块无效）
            projectPath = System.getProperty("user.dir");
        }
        // 打印工程路径
        System.out.println("projectPath = " + projectPath);

        String finalProjectPath = projectPath;
        FastAutoGenerator
                /*
                数据库配置
                 */.create("jdbc:mysql://47.107.229.21:3306/big_data_studio?serverTimezone=GMT%2B8&" + "useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true", // jdbc 路径
                        "bigdatastudio", // 数据库账号
                        "bigdatastudio" // 数据库密码
                )
                /*
                全局配置
                 */.globalConfig((scanner, builder) -> {
                    builder.author(scanner.apply("请输入作者名称？")) // 作者名
                            .fileOverride() // 覆盖已生成文件 false
                            .disableOpenDir() // 打开输出目录 true
                            .outputDir(finalProjectPath + "\\src\\main\\java") // 指定输出目录
//                          .enableSwagger() // 开启swagger模式 false
                            .dateType(DateType.TIME_PACK) // 时间策略
                            .commentDate("yyyy-MM-dd"); // 注释日期
                })
                /*
                包配置
                 */.packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名？")) // 父包名
                                .entity("entity") // Entity包名
                                .service("service") // Service包名
                                .serviceImpl("service.impl") // ServiceImpl 包名
                                .mapper("mapper") // Mapper包名
                                .controller("controller") // Controller包名
                                .other("config") // 自定义文件包名 输出自定义文件时所用到的包名)
                                .pathInfo // 路径配置信息	Collections.singletonMap(OutputFile.mapperXml, "D://")
                                        (Collections.singletonMap(OutputFile.mapperXml, finalProjectPath + "\\src\\main\\resources\\mapper"))
//                                        .xml("mapper.xml") // MapperXML包名
//                                        .moduleName("test") // 父包模块名
                )
                /*
                策略配置
                 */.strategyConfig((scanner, builder) -> {
                    builder.addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔？所有输入 all"))) // 增加表匹配(内存过滤) include与exclude只能配置一项
//                            .addExclude() // 排除掉某些表
                            .addTablePrefix("ow_", "sys_") // 增加过滤表前缀 addTableSuffix增加过滤表后缀
                            .addFieldPrefix("hw_") // 增加过滤字段前缀 addFieldSuffix增加过滤字段后缀
                            .enableCapitalMode() // 开启大写命名 false
//                            .enableSkipView() // 开启跳过视图 false
//                          .disableSqlFilter() // 禁用sql过滤 语法不能支持使用sql过滤表的话，可以考虑关闭此开关 true
//                          .likeTable( // 模糊表匹配(sql过滤) likeTable与notLikeTable只能配置一项
//                                  new LikeTable("USER")
//                          )
                            /*
                            Entity策略配置
                             */.entityBuilder().enableLombok() // 开启lombok模型 false
//                            .enableRemoveIsPrefix() // 开启Boolean类型字段移除is前缀 false
                            .enableTableFieldAnnotation() // 开启生成实体时生成字段注解 false
                            .logicDeleteColumnName("is_deleted") // 逻辑删除字段名(数据库)
                            .logicDeletePropertyName("deleted") // 逻辑删除属性名(实体)
                            .naming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略 默认下划线转驼峰命名
                            .columnNaming(NamingStrategy.underline_to_camel) // 数据库表字段映射到实体的命名策略
                            .idType(IdType.AUTO) // 全局主键类型
                            .addTableFills  // 添加表字段填充
                            (new Property("createName", FieldFill.INSERT), new Property("createTime", FieldFill.INSERT), new Property("updateName", FieldFill.INSERT_UPDATE), new Property("updateTime", FieldFill.INSERT_UPDATE)).addIgnoreColumns("a", "b", "c") // 添加忽略字段
//                            .disableSerialVersionUID() // 生成serialVersionUID true
//                            .enableChainModel() // 开启链式模型 false
//                            .enableActiveRecord() // 开启ActiveRecord模型 false
//                          .versionColumnName("test") // 乐观锁字段名(数据库)
//                          .versionPropertyName("test") // 乐观锁属性名(实体)
//                            .superClass("") // 设置父类
//                            .addSuperEntityColumns // 添加父类公共字段
//                            (
//                                    "id", "create_name", "create_time", "update_name",
//                                    "update_time", "is_delete"
//                            )
                            /*
                            Controller策略配置
                             */.controllerBuilder().enableHyphenStyle() // 开启驼峰转连字符 false
                            .enableRestStyle() // 开启生成@RestController控制器 false
                            .formatFileName("%sController") // 格式化文件名称
//                            .superClass("") // 设置父类
                            /*
                            Service策略配置
                             */.serviceBuilder().formatServiceFileName("%sService") // 转换service接口文件名称
                            .formatServiceImplFileName("%sServiceImpl") // 格式化service接口文件名称
//                            .superServiceClass("") // 设置service接口父类
//                            .superServiceImplClass("") // 设置service实现类父类
                            /*
                            Mapper策略配置
                             */.mapperBuilder().superClass(BaseMapper.class) // 设置父类
                            .enableMapperAnnotation() // 开启@Mapper注解
                            .enableBaseResultMap() // 启用BaseResultMap生成
                            .enableBaseColumnList() // 启用 BaseColumnList
                            .formatMapperFileName("%sMapper") // 格式化mapper文件名称
                            .formatXmlFileName("%sMapperXml"); // 格式化xml实现类文件名称
//                            .cache(MyBatisCache.class); // 设置缓存实现类 如：MyMapperCache.class
                })
                // 模板引擎配置，默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                .templateEngine(new FreemarkerTemplateEngine()).execute();

    }

    /**
     * <h2>处理 all 情况</h2>
     */
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

}
